﻿using System;
using System.Drawing;
using System.IO;
using Glider.Common.Objects;
using System.Threading;

namespace AdvancedMap
{
    class MpqManager
    {
        // Glider directory to store extracted maps
        private string mapDir = Directory.GetCurrentDirectory() + "\\Classes\\Maps\\";

        // Directory in mpqs to look for maps
        private string mpqMapDir = "textures\\Minimap\\";

        // Mpqs to include
        private string[] archiveNames = { "enUS\\locale-enUS.MPQ", "patch.MPQ", "expansion.MPQ", "common-2.MPQ", 
                                            "common.MPQ" };

        // Tile size (WoW scale)
        const float TILESIZE = (float)(1600 / 3);

        // Chunk size per tile (WoW scale)
        const float CHUNKSIZE = (float)TILESIZE / (float)16;

        // Unit size per chunk (WoW scale)
        const float UNITSIZE = (float)CHUNKSIZE / (float)8;

        // Zero point of WoW continent (WoW scale)
        const float ZEROPOINT = (float)32 * TILESIZE;

        // Number of tiles to load (+- from current tile in every direction)
        const int TOFFSET = 2;

        // Maximum number of tiles to keep in memory
        const int MAXTILES = 40;

        // Global vars
        private static bool time = true;
        private static bool debug = false;
        private static bool loggingStatus = false;

        // Archive set
        StormDll.ArchiveSet archive = null;

        // Game directory
        string gameDir;

        /// <summary>
        /// MpqManager constructor
        /// </summary>
        public MpqManager()
        {
            try
            {
                // Initialize archive set
                archive = new StormDll.ArchiveSet();

                // Read game directory from registry
                gameDir = archive.SetGameDirFromReg();

                // Add all mpqs to archive
                archive.AddArchives(archiveNames);
            }
            catch (Exception e)
            {
                Log(e.ToString());
            }
        }

        /// <summary>
        /// Extract a blp2 image from mpqs and convert it to a bmp/jpg file
        /// </summary>
        /// <param name="strTarget">Target blp image path and name</param>
        /// <param name="strName">Extracted image path and name</param>
        public Bitmap ExtractBmp(string strTarget, string strName)
        {
            Bitmap bmpRtn = null;

            try
            {
                // Open strTarget file in mpq archives
                StormDll.File fleBmp = archive.OpenFile(strTarget);

                // Convert strTarget file in mpq archives into jpg image
                bmpRtn = fleBmp.Blp2Bmp(strName);

                // Close file
                fleBmp.Close();
            }
            catch (Exception e)
            {
                Log(e.ToString());
            }

            return bmpRtn;
        }

        private void GLog(string print)
        {
            string temp = "";
            if (time)
                temp += String.Format("{0} - ", DateTime.Now.ToString("hh:mm:ss.mm"));
            if (debug)
                temp += Convert.ToString(Thread.CurrentThread.GetHashCode()) + " - ";
            temp += print;
            GContext.Main.Log(temp);
        }

        public void Log(string print)
        {

            if (loggingStatus)
            {

                string temp = "";
                string file = Directory.GetCurrentDirectory() + "\\Classes\\Maps\\Log.txt";

                try
                {
                    TextWriter output = TextWriter.Synchronized(System.IO.File.AppendText(file));

                    if (time)
                        temp += String.Format("{0} - ", DateTime.Now.ToString("hh:mm:ss.mm"));
                    if (debug)
                        temp += Convert.ToString(Thread.CurrentThread.GetHashCode()) + " - ";
                    temp += print;
                    output.WriteLine(temp);
                    output.Close();
                }
                catch
                {
                    GLog("Error in SaveToFile()");
                }
            }
            else
            {
                GLog(print);
            }
        }
    }
}
